package com.slicktechnologies.shared.common.businessprocesslayer;

import java.util.Date;
import java.util.Vector;

import com.google.gwt.core.shared.GwtIncompatible;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.OnSave;
import com.simplesoftwares.client.library.appstructure.SuperModel;
import com.simplesoftwares.client.library.appstructure.search.Filter;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.helperconstants.ColumnDatatype;
import com.simplesoftwares.client.library.helperconstants.FormTypes;
import com.simplesoftwares.rebind.annatonations.SearchAnnotation;
import com.simplesoftwares.rebind.annatonations.SearchCompositeAnnatonation;
import com.simplesoftwares.rebind.annatonations.TableAnnotation;
import com.slicktechnologies.server.GenricServiceImpl;
import com.slicktechnologies.shared.MyUtility;
import com.slicktechnologies.shared.common.helperlayer.Config;
import com.slicktechnologies.shared.common.helperlayer.ConfigCategory;
import com.slicktechnologies.shared.common.helperlayer.Type;
import com.slicktechnologies.shared.common.relationalLayer.BranchRelation;
import com.slicktechnologies.shared.common.relationalLayer.EmployeeRelation;

/**
 * Super class of all BuisnessProcess.
 */
@Embed
@Entity

public class ConcreteBusinessProcess extends SuperModel implements BusinessProcess,ApprovableProcess
{
	/***********************************************Entity Attributes****************************************************/
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -4248761701435837923L;
	public static final String CREATED="Created",CANCELLED="Cancelled",REJECTED="Rejected",APPROVED="Approved",REQUESTED="Requested";

	/**  The status of this {@link BusinessProcess}. */
	@Index
	protected String status;

	/**  The employee assigned for this {@link BusinessProcess}.
	 * employee can be creator, approver, can manage business process or can be combination of this */
	@Index
	protected String employee;

	/**  The branch of this {@link BusinessProcess}. */
	@Index
	protected String branch;

	
	/**Creation Time of this {@link BusinessProcess}*/
	protected String creationTime;

	/**Approval Time of this {@link BusinessProcess}*/
	protected String approvalTime;
	
	
	/**  The creation date for this {@link BusinessProcess}. */
	@Index 
	protected Date creationDate;

	/**  The business process approval date for this {@link BusinessProcess}. */
	@Index
	protected Date approvalDate;

	/**  The business process approver name for this {@link BusinessProcess}. */
	@Index
	protected String approverName;
	
	/**
	 * Group of this business Process
	 */
	@Index
	protected String group;
	
	/**
	 * Category of this buisness Process
	 */
	@Index
	protected String category;
	
	/**
	 * Type of this buisness Process
	 */
	@Index
	protected String type;
	
	/***********************************************Relational Attributes****************************************************/
	protected Key<Config> statusKey;
	protected Key<BranchRelation>keyNameBranch;
	protected Key<EmployeeRelation>keyNameEmployee;
	protected Key<Type> typeKey;
	protected Key<Config> groupKey;
	protected Key<ConfigCategory> categoryKey;
	
	/**********************************************Default Ctor*****************************************************/
	
	/**
	 * Instantiates a new concrete business process.
	 */
	public ConcreteBusinessProcess() 
	{
		super();
		status="";
		employee="";
		branch="";
		creationTime="";
		approvalTime="";
		creationDate=new Date();
		approverName="";
		this.group="";
		this.category="";
		this.type="";
		this.status=CREATED;
		
	}

	/**
	 * Instantiates a new concrete business process.
	 * @param status -status set for the {@link BusinessProcess}
	 * @param employee -employee alloted for the {@link BusinessProcess}
	 * @param branch -branch selected for the {@link BusinessProcess}
	 * @param creationDate -creation date set for the {@link BusinessProcess}
	 */
	public ConcreteBusinessProcess(String status, String employee, String branch,Date creationDate) 
	{
		super();
		this.status = status;
		this.employee = employee;
		this.branch = branch;
		this.creationDate = creationDate;
	}

	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(SuperModel arg0)
	{
		BusinessProcess process=(BusinessProcess) arg0;
		if(creationDate!=null)
			
			return creationDate.compareTo(process.getCreationDate());
		else 
			return 0;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.helperlayer.SuperModel#isDuplicate(com.simplesoftwares.shared.helperlayer.SuperModel)
	 */
	@Override
	public boolean isDuplicate(SuperModel m)
	{
		return false;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#getBranch()
	 */
	/**
	 * Get the Branch corresponding to this  {@link BusinessProcess}.
	 *
	 * @return the branch
	 */
	@Override
	@SearchAnnotation(Datatype = ColumnDatatype.OBJECTLISTBOXBRANCH, flexFormNumber = "11", title = "Branch", variableName = "olbBranch")
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 2, isFieldUpdater = false, isSortable = true, title = "Branch")
	public String getBranch()
	{
		return branch;
	}

	/* (non-Javadocg)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#getEmployee()
	 */
	@SearchAnnotation(Datatype = ColumnDatatype.OBJECTLISTBOXEMPLOYEE, flexFormNumber = "10", title = "Employee", variableName = "olbEmployee")
	@Override
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 3, isFieldUpdater = false, isSortable = true, title = "Sales Person")
	public String getEmployee() 
	{
		return employee;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#getStatus()
	 */
	@Override

		@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 4, isFieldUpdater = false, isSortable = true, title = "Status")
	public String getStatus() 
	{
		return status;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#setBranch(java.lang.String)
	 */
	@Override
	public void setBranch(String branch) 
	{
		if(branch!=null)
			this.branch=branch.trim();

	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#setEmployee(java.lang.String)
	 */
	@Override
	public void setEmployee(String employee)
	{
		if(employee!=null)
			this.employee=employee.trim();

	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#setStatus(java.lang.String)
	 */
	@Override
	public void setStatus(String status) 
	{
		if(status!=null)
			this.status=status.trim();
	}



	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#setCreationDate(java.util.Date)
	 */
	@Override
	public void setCreationDate(Date date)
	{
		if(date!=null)
			creationDate=date;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#getCreationDate()
	 */
	@Override
	@SearchAnnotation(Datatype = ColumnDatatype.DATECOMPARATOR, flexFormNumber = "00", title = "Creation Date", variableName = "dateComparator",extra="Lead")
	@TableAnnotation(ColType = FormTypes.DATETEXTCELL, colNo = 1, isFieldUpdater = false, isSortable = false, title = "Creation Date")
	public Date getCreationDate() 
	{
		return creationDate;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#getApproverName()
	 */
	
	@Override
	public String getApproverName() 
	{

		return this.approverName.trim();
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#getApprovalDate()
	 */
	@Override
	public Date getApprovalDate() 
	{

		return this.approvalDate;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#setApproverName(java.lang.String)
	 */
	@Override
	public void setApproverName(String name)
	{
		if(name!=null)
			this.approverName=name.trim();
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.shared.businessprocesslayer.BuisnessProcess#setApprovalDate(java.util.Date)
	 */
	@Override
	public void setApprovalDate(Date date) 
	{
		if(date!=null)
			this.approvalDate=date;
	}

	public String getCreationTime() {
		return creationTime;
	}

	public String getApprovalTime() {
		return approvalTime;
	}

	public void setCreationTime(String time) 
	{
		if(time!=null)
			this.creationTime=time.trim();
	}
	
	public void setApprovalTime(String time) 
	{
		if(time!=null)
			this.approvalTime=time.trim();
	}
	
	public Key<Config> getStatusKey() {
		return statusKey;
	}

	public void setStatusKey(Key<Config> statusKey) {
		this.statusKey = statusKey;
	}

	public Key<BranchRelation> getKeyNameBranch() {
		return keyNameBranch;
	}

	public void setKeyNameBranch(Key<BranchRelation> keyNameBranch) {
		this.keyNameBranch = keyNameBranch;
	}

	public Key<EmployeeRelation> getKeyNameEmployee() {
		return keyNameEmployee;
	}

	public void setKeyNameEmployee(Key<EmployeeRelation> keyNameEmployee) {
		this.keyNameEmployee = keyNameEmployee;
	}
	
	
	
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo =5 , isFieldUpdater = false, isSortable = true, title = "Group")
	public String getGroup() {
		return group;
	}

	public void setGroup(String group) {
		if(group!=null)
		  this.group = group.trim();
	}

	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 6, isFieldUpdater = false, isSortable = true, title = "Category")
	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		if(category!=null)
		this.category = category.trim();
	}

	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 7, isFieldUpdater = false, isSortable = true, title = "Type")
	public String getType() {
		return type;
	}

	public void setType(String type) {
		if(this.type!=null)
		  this.type = type.trim();
	}

	public Key<Type> getTypeKey() {
		return typeKey;
	}

	public void setTypeKey(Key<Type> typeKey) {
		this.typeKey = typeKey;
	}

	public Key<Config> getGroupKey() {
		return groupKey;
	}

	public void setGroupKey(Key<Config> groupKey) {
		this.groupKey = groupKey;
	}

	public Key<ConfigCategory> getCategoryKey() {
		return categoryKey;
	}

	public void setCategoryKey(Key<ConfigCategory> categoryKey) {
		this.categoryKey = categoryKey;
	}

	/**************************************************Relation Managment Part**********************************************/
	  @GwtIncompatible
	  @OnSave
	  public void OnSave()
	  {
		 // if(id==null)
			{
				if(id==null)
				  setCreationDate(GenricServiceImpl.parseDate());
				System.out.println("Creation Date is "+this.creationDate);
				MyQuerry querry=new MyQuerry();
			  	Vector<Filter>filter=new Vector<Filter>();
			  	Filter nameFilter=new Filter();
			  	nameFilter.setStringValue(this.branch);
			  	nameFilter.setQuerryString("branchName");
			  	filter.add(nameFilter);
			  	querry.setFilters(filter);
			  	querry.setQuerryObject(new BranchRelation());
			  	keyNameBranch=(Key<BranchRelation>) MyUtility.getRelationalKeyFromCondition(querry);
			  	
			  	querry=new MyQuerry();
			  	filter=new Vector<Filter>();
			  	nameFilter=new Filter();
			  	nameFilter.setStringValue(this.employee);
			  	nameFilter.setQuerryString("employeeName");
			  	filter.add(nameFilter);
			  	querry.setFilters(filter);
			  	
				querry.setQuerryObject(new EmployeeRelation());
			  	keyNameEmployee=(Key<EmployeeRelation>) MyUtility.getRelationalKeyFromCondition(querry);
			}  
	  }
	  @GwtIncompatible
	  @OnLoad
	  public void OnLoad()
	  {
		  //Get Entity From Key for Branch 
		  if(keyNameBranch!=null)
		  {
		    String branchName=MyUtility.getBranchNameFromKey(keyNameBranch);
		    if(branchName.equals("")==false)
		    	setBranch(branchName);
	
		  }
		  
		  //Get Entity From Key for Employee
		  if(keyNameEmployee!=null)
		  {
			  String employeeName=MyUtility.getEmployeeNameFromKey(keyNameEmployee);
			  if(employeeName.equals("")==false)
				  setEmployee(employeeName);
		     
		  }
		  
		
	  }

	@Override
	public void reactOnApproval() {
		// TODO Auto-generated method stub
		
	}

	/*
	protected ConcreteBusinessProcess clone() throws CloneNotSupportedException {
		ConcreteBusinessProcess buisnBusinessProcess=new ConcreteBusinessProcess();
		buisnBusinessProcess.id=null;
		
		buisnBusinessProcess.companyId=companyId;
		buisnBusinessProcess.setDeleted(isDeleted());
		buisnBusinessProcess.setStatus(status);
		buisnBusinessProcess.setEmployee(employee);
		buisnBusinessProcess.branch=branch;
		buisnBusinessProcess.creationTime=creationTime;
		buisnBusinessProcess.approvalTime=approvalTime;
		buisnBusinessProcess.creationDate=new Date();
		buisnBusinessProcess.group=group;
		buisnBusinessProcess.category=category;
		buisnBusinessProcess.type=type;
		return buisnBusinessProcess;
	}
*/
	
	  
}
